package com.tater.proxy;

import com.alibaba.fastjson.JSON;
import com.tater.client.NettyClient;
import com.tater.codec.RpcRequest;
import com.tater.codec.RpcResponse;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
import java.util.UUID;

/**
 * @author Administrator
 */
public class RpcProxyFactory<T> implements InvocationHandler {


    private Class<T> interfaceClazz;
 
    private String host;
 
    private Integer port;
 
    public RpcProxyFactory(Class<T> interfaceClazz, String host, Integer port) {
        this.interfaceClazz = interfaceClazz;
        this.host = host;
        this.port = port;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            RpcRequest request = new RpcRequest();
            String requestId = UUID.randomUUID().toString();

            String className = method.getDeclaringClass().getName();
            String methodName = method.getName();

            Class<?>[] parameterTypes = method.getParameterTypes();
            System.out.println("请求方法返回类型getReturnType："+method.getReturnType());

            request.setRequestId(requestId);
            request.setClassName(className);
            request.setMethodName(methodName);
            request.setParameterTypes(parameterTypes);
            request.setParameters(args);

            System.out.println("请求内容: {}"+request);

            //开启Netty 客户端，直连
            NettyClient nettyClient = new NettyClient(host, port);
            System.out.println("开始连接服务端：{}"+ new Date());
            nettyClient.connect();
            RpcResponse send = nettyClient.send(request);

            System.out.println("请求调用返回结果：{}"+ send.getResult());
            if (send.getResult()!=null){
                return JSON.parseObject(send.getResult().toString(),method.getReturnType());
            }else {
                return send.getResult();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public T getProxy() {
        return (T) Proxy.newProxyInstance(
                interfaceClazz.getClassLoader(),
                new Class<?>[]{interfaceClazz},
                this);
    }
}